﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using EricUtility.Windows.Forms;
using TVOnline;
using WatchMoviesHelper.Entities;
using TVOnline.Entities;
using TVOnline.Windows.Forms;
using TVOnline.VideoViewing;

namespace WatchMoviesHelper.Windows.Forms
{
    public delegate void TabPageEventHandler(TabPage t);
    public partial class WatchMoviesTabContent : TabPageContent
    {
        public event TabPageEventHandler AskForANewTab = delegate { };
        private Button old = null;
        private Dictionary<string, AbstractMovieList> movies = new Dictionary<string, AbstractMovieList>();
        private Dictionary<KnownWebsite, CheckBox> btnKnowns = new Dictionary<KnownWebsite, CheckBox>();
        public WatchMoviesTabContent()
        {
            InitializeComponent();
            btnKnowns.Add(KnownWebsite.MegaVideo, btnMegaVideo);
            btnKnowns.Add(KnownWebsite.WiseVid, btnWiseVid);
            btnKnowns.Add(KnownWebsite.ZShare, btnZShare);
            btnKnowns.Add(KnownWebsite.VideoWeed, btnVideoWeed);
            btnKnowns.Add(KnownWebsite.YouTube, btnYouTube);
            btnKnowns.Add(KnownWebsite.MovShare, btnMovShare);
            btnKnowns.Add(KnownWebsite.PlayHD, btnPlayHD);
            btnKnowns.Add(KnownWebsite.NovaMov, btnNovaMov);
            btnKnowns.Add(KnownWebsite.Tudou, btnTudou);
            btnKnowns.Add(KnownWebsite.StageVu, btnStageVu);
        }
        private void btnLetter_Click(object sender, EventArgs e)
        {
            Button btnSender = sender as Button;
            string letter = btnSender.Text;
            if (!movies.ContainsKey(letter))
                movies.Add(letter, new LetterInfo(letter));
            LoadMovieList(btnSender, movies[letter]);
        }
        private void btnYear_Click(object sender, EventArgs e)
        {
            Button btnSender = sender as Button;
            string year = btnSender.Text;
            if (!movies.ContainsKey(year))
                movies.Add(year, new YearInfo(year));
            LoadMovieList(btnSender, movies[year]);
        }
        private void btnGenre_Click(object sender, EventArgs e)
        {
            Button btnSender = sender as Button;
            string genre = btnSender.Text;
            if (!movies.ContainsKey(genre))
                movies.Add(genre, new GenreInfo(genre));
            LoadMovieList(btnSender, movies[genre]);
        }

        private void btnLatest_Click(object sender, EventArgs e)
        {
            Button btnSender = sender as Button;
            if (!movies.ContainsKey("latest"))
                movies.Add("latest", new LatestInfo("newest"));
            LoadMovieList(btnSender, movies["latest"] );
        }

        private void btnSearch_Click(object sender, EventArgs e)
        {
            LoadMovieList(new SearchInfo(txtSearch.Text));

        }
        public void LoadMovieList(Button btnSender, AbstractMovieList list)
        {
            if( btnSender != null )
                btnSender.Enabled = false;
            LoadMovieList(list);
            old = btnSender;
        }
        public void LoadMovieList(AbstractMovieList list)
        {
            statePictureBox1.Etat = EricUtility.Windows.Forms.StatePictureBoxStates.Waiting;
            if (old != null)
                old.Enabled = true;
            lstMovies.Items.Clear();
            lstWebSite.Items.Clear();
            foreach (CheckBox c in btnKnowns.Values)
            {
                c.Enabled = false;
                c.Checked = false;
            }
            btnMagic.Enabled = false;
            lstMirror.Items.Clear();
            lstLink.Items.Clear();
            grpMovieDesc.Visible = false;
            Enabled = false;
            new Thread(new ParameterizedThreadStart(LoadLetter)).Start(list);
        }

        public void LoadLetter(object state)
        {
            AbstractMovieList tl = (AbstractMovieList)state;
            try
            {
                tl.LoadIfNeeded();
                EndLoadLetter(tl);
            }
            catch
            {
                EndLoadLetterBadly(tl);
            }
        }

        public delegate void TupleLetterHandler(AbstractMovieList tl);
        public void EndLoadLetter(AbstractMovieList tl)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new TupleLetterHandler(EndLoadLetter), new object[] { tl });
                return;
            }
            foreach (MovieInfo ts in tl.Movies)
            {
                lstMovies.Items.Add(ts);
            }
            statePictureBox1.Etat = EricUtility.Windows.Forms.StatePictureBoxStates.None;
            Enabled = true;
            if (tl.Movies.Length == 1)
            {
                lstMovies.SelectedIndex = 0;
            }
        }
        public void EndLoadLetterBadly(AbstractMovieList tl)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new TupleLetterHandler(EndLoadLetterBadly), new object[] { tl });
                return;
            }
            statePictureBox1.Etat = EricUtility.Windows.Forms.StatePictureBoxStates.Bad;
            if (old != null)
                old.Enabled = true;
            old = null;
            Enabled = true;
        }

        private void lstMovie_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (lstMovies.SelectedIndex >= 0)
            {
                MovieInfo ts = lstMovies.SelectedItem as MovieInfo;
                statePictureBox1.Etat = EricUtility.Windows.Forms.StatePictureBoxStates.Waiting;
                lstWebSite.Items.Clear();
                foreach (CheckBox c in btnKnowns.Values)
                {
                    c.Enabled = false;
                    c.Checked = false;
                }
                btnMagic.Enabled = false;
                lstMirror.Items.Clear();
                lstLink.Items.Clear();
                Enabled = false;
                new Thread(new ParameterizedThreadStart(LoadMovie)).Start(lstMovies.SelectedItem);
            }
        }

        public void LoadMovie(object state)
        {
            MovieInfo ts = (MovieInfo)state;
            try
            {
                ts.LoadIfNeeded();
                EndLoadMovie(ts);
            }
            catch
            {
                EndLoadMovieBadly(ts);
            }
        }
        public delegate void TupleMovieHandler(MovieInfo tl);
        public void EndLoadMovie(MovieInfo te)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new TupleMovieHandler(EndLoadMovie), new object[] { te });
                return;
            }
            foreach (WebsiteMovieInfo tw in te.WebSites)
            {
                if (!btnKnowns.ContainsKey(tw.TypeWebSite))
                    lstWebSite.Items.Add(tw);
            }
            foreach (KeyValuePair<KnownWebsite, CheckBox> kvp in btnKnowns)
                kvp.Value.Enabled = (te.KnownWebSite(kvp.Key) != null);
            statePictureBox1.Etat = EricUtility.Windows.Forms.StatePictureBoxStates.None;
            grpMovieDesc.Visible = true;
            grpMovieDesc.Text = te.Name;
            lblShowDesc.Text = te.Description;
            Enabled = true;
            if (te.WebSites.Length == 1)
            {
                lstWebSite.SelectedIndex = 0;
            }
        }
        public void EndLoadMovieBadly(MovieInfo ts)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new TupleMovieHandler(EndLoadMovieBadly), new object[] { ts });
                return;
            }
            statePictureBox1.Etat = EricUtility.Windows.Forms.StatePictureBoxStates.Bad;
            lstMovies.SelectedIndex = -1;
            Enabled = true;
        }

       

        private void lstWebSite_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (lstWebSite.SelectedIndex >= 0)
            {
                lstMirror.Items.Clear();
                lstLink.Items.Clear();
                btnMagic.Enabled = false;
                WebsiteInfo tw = (WebsiteInfo)lstWebSite.SelectedItem;
                foreach (LinkInfo tm in tw.Mirrors)
                {
                    lstMirror.Items.Add(tm);
                }
                if (tw.Mirrors.Length == 1)
                {
                    lstMirror.SelectedIndex = 0;
                }
            }
        }
        private void KnownWebSiteClick(KnownWebsite t)
        {
            foreach (KeyValuePair<KnownWebsite,CheckBox> kvp in btnKnowns)
                kvp.Value.Checked = (t == kvp.Key);
            if (t != KnownWebsite.Others)
                lstWebSite.SelectedIndex = -1;
            if (lstMovies.SelectedIndex >= 0)
            {
                MovieInfo te = (MovieInfo)lstMovies.SelectedItem;
                WebsiteInfo tw = te.KnownWebSite(t);
                if (tw != null)
                {
                    lstWebSite.SelectedIndex = -1;
                    lstMirror.Items.Clear();
                    lstLink.Items.Clear();
                    btnMagic.Enabled = false;
                    foreach (LinkInfo tm in tw.Mirrors)
                    {
                        lstMirror.Items.Add(tm);
                    }
                    if (tw.Mirrors.Length == 1)
                    {
                        lstMirror.SelectedIndex = 0;
                    }
                }
            }
        }
        private void btnMegaVideo_Click(object sender, EventArgs e)
        {
            KnownWebSiteClick(KnownWebsite.MegaVideo);
        }

        private void btnWiseVid_Click(object sender, EventArgs e)
        {
            KnownWebSiteClick(KnownWebsite.WiseVid);
        }

        private void btnZShare_Click(object sender, EventArgs e)
        {
            KnownWebSiteClick(KnownWebsite.ZShare);
        }

        private void btnVideoWeed_Click(object sender, EventArgs e)
        {
            KnownWebSiteClick(KnownWebsite.VideoWeed);
        }

        private void btnYouTube_CheckedChanged(object sender, EventArgs e)
        {
        }

        private void btnMovShare_Click(object sender, EventArgs e)
        {
            KnownWebSiteClick(KnownWebsite.MovShare);
        }

        private void btnPlayHD_Click(object sender, EventArgs e)
        {
            KnownWebSiteClick(KnownWebsite.PlayHD);

        }

        private void btnNovaMov_Click(object sender, EventArgs e)
        {
            KnownWebSiteClick(KnownWebsite.NovaMov);

        }

        private void btnYouTube_Click(object sender, EventArgs e)
        {
            KnownWebSiteClick(KnownWebsite.YouTube);
        }

        private void lstMirror_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (lstMirror.SelectedIndex >= 0)
            {
                lstLink.Items.Clear();
                btnMagic.Enabled = false;
                LinkInfo tw = (LinkInfo)lstMirror.SelectedItem;
                foreach (LinkPartInfo tl in tw.Links)
                {
                    lstLink.Items.Add(tl);
                }
                if (tw.Links.Length >= 1)
                {
                    lstLink.SelectedIndex = 0;
                }
            }
        }

        private void lstLink_SelectedIndexChanged(object sender, EventArgs e)
        {
            btnMagic.Enabled = (lstLink.SelectedIndex >= 0);
            if (lstLink.SelectedIndex >= 0)
            {
                statePictureBox1.Etat = EricUtility.Windows.Forms.StatePictureBoxStates.Waiting;
                Enabled = false;
                new Thread(new ParameterizedThreadStart(LoadLink)).Start(lstLink.SelectedItem);
            }
        }


        public void LoadLink(object state)
        {
            LinkPartInfo tl = (LinkPartInfo)state;
            try
            {
                tl.LoadIfNeeded();
                EndLoadLink(tl);
            }
            catch
            {
                EndLoadLinkBadly(tl);
            }
        }
        public delegate void TupleLinkHandler(LinkPartInfo tl);
        public void EndLoadLink(LinkPartInfo tl)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new TupleLinkHandler(EndLoadLink), new object[] { tl });
                return;
            }
            statePictureBox1.Etat = EricUtility.Windows.Forms.StatePictureBoxStates.None;
            Enabled = true;
        }
        public void EndLoadLinkBadly(LinkPartInfo tl)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new TupleLinkHandler(EndLoadLinkBadly), new object[] { tl });
                return;
            }
            statePictureBox1.Etat = EricUtility.Windows.Forms.StatePictureBoxStates.Bad;
            lstLink.SelectedIndex = -1;
            Enabled = true;
        }
        private void MainForm_Load(object sender, EventArgs e)
        {
        }

        private void btnMagic_Click(object sender, EventArgs e)
        {
            statePictureBox1.Etat = EricUtility.Windows.Forms.StatePictureBoxStates.Waiting;
            Enabled = false;
            new Thread(new ParameterizedThreadStart(WatchLink)).Start(lstLink.SelectedItem);
        }
        public void WatchLink(object state)
        {
            LinkPartInfo tl = (LinkPartInfo)state;
            try
            {
                tl.LoadViewer();
                EndWatchLink(tl.Viewer);
            }
            catch
            {
                EndWatchLinkBadly(null);
            }
        }

        public delegate void TupleWatchLinkHandler(AbstractViewer viewer);
        private void EndWatchLink(AbstractViewer viewer)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new TupleWatchLinkHandler(EndWatchLink), new object[] { viewer });
                return;
            }
            MovieInfo ep = lstMovies.SelectedItem as MovieInfo;
            string title = ep.Name;
            if (viewer is ErrorViewer)
            {
                MessageBox.Show(((ErrorViewer)viewer).Error, title, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            else if (viewer is WebBrowserViewer)
            {
                WebBrowserViewer v = viewer as WebBrowserViewer;
                CustomizedTabPage t = new CustomizedTabPage(new WebBrowserTabContent(v.ViewUrl, v.Url));
                t.Text = title;
                AskForANewTab(t);
            }
            else if (viewer is FlashViewer)
            {
                FlashViewer v = viewer as FlashViewer;
                CustomizedTabPage t = new CustomizedTabPage(new FlashMovieTabContent(v.Movie, v.FlashVars, v.Url));
                t.Text = title;
                AskForANewTab(t);
            }
            else if (viewer is FlashPlayerViewer)
            {
                FlashPlayerViewer v = viewer as FlashPlayerViewer;
                CustomizedTabPage t = new CustomizedTabPage(new CustomizedFlashMovieTabContent(v.Player, v.Movie, v.DownloadLink, v.Url));
                t.Text = title;
                AskForANewTab(t);
            }
            else if (viewer is DivxPlayerViewer)
            {
                DivxPlayerViewer v = viewer as DivxPlayerViewer;
                CustomizedTabPage t = new CustomizedTabPage(new DivxDownloadTabContent(v.DownloadLink, v.Url));
                t.Text = title;
                AskForANewTab(t);
            }
            else
                System.Diagnostics.Process.Start(viewer.Url);
            statePictureBox1.Etat = EricUtility.Windows.Forms.StatePictureBoxStates.None;
            Enabled = true;
        }

        private void EndWatchLinkBadly(AbstractViewer viewer)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new TupleWatchLinkHandler(EndWatchLinkBadly), new object[] { viewer });
                return;
            }
            statePictureBox1.Etat = EricUtility.Windows.Forms.StatePictureBoxStates.Bad;
            Enabled = true;
        }

        private void WatchMoviesTabContent_Resize(object sender, EventArgs e)
        {
            SuspendLayout();
            const int allBaseWidth = 846;
            const int allBaseHeight = 529;
            int xdiff = Width - allBaseWidth;
            int ydiff = Height - allBaseHeight;

            int rowDelta = (xdiff / 3);

            //Buttons
            pnlButtons.Location = new Point(pnlButtons.Left, (Height / 2) - (pnlButtons.Height / 2));



            // Row Mirrors
            const int mirrorBaseWidth = 185;
            const int mirrorX = 650;
            int mirrorOffset = (2 * rowDelta);
            lblTitMirrors.Size = new Size(mirrorBaseWidth + rowDelta, lblTitMirrors.Height);
            lblTitMirrors.Location = new Point(mirrorX + mirrorOffset, lblTitMirrors.Top);
            lblTitParts.Size = new Size(mirrorBaseWidth + rowDelta, lblTitParts.Height);
            lblTitParts.Location = new Point(mirrorX + mirrorOffset, lblTitParts.Top);
            lstMirror.Size = new Size(mirrorBaseWidth + rowDelta, lstMirror.Height);
            lstMirror.Location = new Point(mirrorX + mirrorOffset, lstMirror.Top);
            lstLink.Size = new Size(mirrorBaseWidth + rowDelta, lstLink.Height);
            lstLink.Location = new Point(mirrorX + mirrorOffset, lstLink.Top);
            btnMagic.Size = new Size(mirrorBaseWidth + rowDelta, btnMagic.Height);
            btnMagic.Location = new Point(mirrorX + mirrorOffset, btnMagic.Top);

            // Row Websites
            const int websiteBaseWidth = 182;
            const int websiteX = 462;
            int websiteOffset = (1 * rowDelta);
            lblTitWebsite.Size = new Size(websiteBaseWidth + rowDelta, lblTitWebsite.Height);
            lblTitWebsite.Location = new Point(websiteX + websiteOffset, lblTitWebsite.Top);
            lstWebSite.Size = new Size(websiteBaseWidth + rowDelta, lstWebSite.Height);
            lstWebSite.Location = new Point(websiteX + websiteOffset, lstWebSite.Top);
            foreach (CheckBox btn in btnKnowns.Values)
            {
                btn.Size = new Size(websiteBaseWidth + rowDelta, btn.Height);
                btn.Location = new Point(websiteX + websiteOffset, btn.Top);
            }

            // Row Movie
            const int episodeBaseWidth = 185;
            const int episodeX = 271;
            int episodeOffset = 0;
            lblTitMovies.Size = new Size(episodeBaseWidth + rowDelta, lblTitMovies.Height);
            lblTitMovies.Location = new Point(episodeX + episodeOffset, lblTitMovies.Top);
            lstMovies.Size = new Size(episodeBaseWidth + rowDelta, lstMovies.Height);
            lstMovies.Location = new Point(episodeX + episodeOffset, lstMovies.Top);

            this.ResumeLayout(false);
            this.PerformLayout();
        }

        private void btnPopular_Click(object sender, EventArgs e)
        {
            Button btnSender = sender as Button;
            if (!movies.ContainsKey("popular"))
                movies.Add("popular", new LatestInfo("popular"));
            LoadMovieList(btnSender, movies["popular"]);
        }

        private void btn09_Click(object sender, EventArgs e)
        {
            Button btnSender = sender as Button;
            string letter = "09";
            if (!movies.ContainsKey(letter))
                movies.Add(letter, new LetterInfo(letter));
            LoadMovieList(btnSender, movies[letter]);

        }

        private void btnGoYear_Click(object sender, EventArgs e)
        {
            string year = ((int)nudYear.Value).ToString();
            if (!movies.ContainsKey(year))
                movies.Add(year, new YearInfo(year));
            LoadMovieList(null, movies[year]);
        }

        private void txtSearch_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
                btnSearch_Click(sender, e);
        }

        private void nudYear_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
                btnGoYear_Click(sender, e);
        }
    }
}
